#region Copyright (c) 2006-2011 Widgetsphere LLC, All Rights Reserved
//--------------------------------------------------------------------- *
//                          Widgetsphere  LLC                           *
//             Copyright (c) 2006-2011 All Rights reserved              *
//                                                                      *
//                                                                      *
//This file and its contents are protected by United States and         *
//International copyright laws.  Unauthorized reproduction and/or       *
//distribution of all or any portion of the code contained herein       *
//is strictly prohibited and will result in severe civil and criminal   *
//penalties.  Any violations of this copyright will be prosecuted       *
//to the fullest extent possible under law.                             *
//                                                                      *
//THE SOURCE CODE CONTAINED HEREIN AND IN RELATED FILES IS PROVIDED     *
//TO THE REGISTERED DEVELOPER FOR THE PURPOSES OF EDUCATION AND         *
//TROUBLESHOOTING. UNDER NO CIRCUMSTANCES MAY ANY PORTION OF THE SOURCE *
//CODE BE DISTRIBUTED, DISCLOSED OR OTHERWISE MADE AVAILABLE TO ANY     *
//THIRD PARTY WITHOUT THE EXPRESS WRITTEN CONSENT OF WIDGETSPHERE LLC   *
//                                                                      *
//UNDER NO CIRCUMSTANCES MAY THE SOURCE CODE BE USED IN WHOLE OR IN     *
//PART, AS THE BASIS FOR CREATING A PRODUCT THAT PROVIDES THE SAME, OR  *
//SUBSTANTIALLY THE SAME, FUNCTIONALITY AS ANY WIDGETSPHERE PRODUCT.    *
//                                                                      *
//THE REGISTERED DEVELOPER ACKNOWLEDGES THAT THIS SOURCE CODE           *
//CONTAINS VALUABLE AND PROPRIETARY TRADE SECRETS OF WIDGETSPHERE,      *
//INC.  THE REGISTERED DEVELOPER AGREES TO EXPEND EVERY EFFORT TO       *
//INSURE ITS CONFIDENTIALITY.                                           *
//                                                                      *
//THE END USER LICENSE AGREEMENT (EULA) ACCOMPANYING THE PRODUCT        *
//PERMITS THE REGISTERED DEVELOPER TO REDISTRIBUTE THE PRODUCT IN       *
//EXECUTABLE FORM ONLY IN SUPPORT OF APPLICATIONS WRITTEN USING         *
//THE PRODUCT.  IT DOES NOT PROVIDE ANY RIGHTS REGARDING THE            *
//SOURCE CODE CONTAINED HEREIN.                                         *
//                                                                      *
//THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE.              *
//--------------------------------------------------------------------- *
#endregion
#region Copyright (c) 2006-2011 Widgetsphere LLC, All Rights Reserved
//--------------------------------------------------------------------- *
//                          Widgetsphere  LLC                           *
//             Copyright (c) 2006-2011 All Rights reserved              *
//                                                                      *
//                                                                      *
//This file and its contents are protected by United States and         *
//International copyright laws.  Unauthorized reproduction and/or       *
//distribution of all or any portion of the code contained herein       *
//is strictly prohibited and will result in severe civil and criminal   *
//penalties.  Any violations of this copyright will be prosecuted       *
//to the fullest extent possible under law.                             *
//                                                                      *
//THE SOURCE CODE CONTAINED HEREIN AND IN RELATED FILES IS PROVIDED     *
//TO THE REGISTERED DEVELOPER FOR THE PURPOSES OF EDUCATION AND         *
//TROUBLESHOOTING. UNDER NO CIRCUMSTANCES MAY ANY PORTION OF THE SOURCE *
//CODE BE DISTRIBUTED, DISCLOSED OR OTHERWISE MADE AVAILABLE TO ANY     *
//THIRD PARTY WITHOUT THE EXPRESS WRITTEN CONSENT OF WIDGETSPHERE LLC   *
//                                                                      *
//UNDER NO CIRCUMSTANCES MAY THE SOURCE CODE BE USED IN WHOLE OR IN     *
//PART, AS THE BASIS FOR CREATING A PRODUCT THAT PROVIDES THE SAME, OR  *
//SUBSTANTIALLY THE SAME, FUNCTIONALITY AS ANY WIDGETSPHERE PRODUCT.    *
//                                                                      *
//THE REGISTERED DEVELOPER ACKNOWLEDGES THAT THIS SOURCE CODE           *
//CONTAINS VALUABLE AND PROPRIETARY TRADE SECRETS OF WIDGETSPHERE,      *
//INC.  THE REGISTERED DEVELOPER AGREES TO EXPEND EVERY EFFORT TO       *
//INSURE ITS CONFIDENTIALITY.                                           *
//                                                                      *
//THE END USER LICENSE AGREEMENT (EULA) ACCOMPANYING THE PRODUCT        *
//PERMITS THE REGISTERED DEVELOPER TO REDISTRIBUTE THE PRODUCT IN       *
//EXECUTABLE FORM ONLY IN SUPPORT OF APPLICATIONS WRITTEN USING         *
//THE PRODUCT.  IT DOES NOT PROVIDE ANY RIGHTS REGARDING THE            *
//SOURCE CODE CONTAINED HEREIN.                                         *
//                                                                      *
//THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE.              *
//--------------------------------------------------------------------- *
#endregion

using System;
using System.Text;
using Widgetsphere.Generator.Models;

namespace Widgetsphere.Generator.DAL.ProjectItemGenerators.DomainStoredProcedure
{
	class DomainStoredProcedureGeneratedTemplate : DomainProjectTemplate
	{

		private readonly StringBuilder sb = new StringBuilder();
		private readonly CustomStoredProcedure _currentStoredProcedure;

		public DomainStoredProcedureGeneratedTemplate(ModelRoot model, CustomStoredProcedure currentStoredProcedure)
		{
			_model = model;
			_currentStoredProcedure = currentStoredProcedure;
		}

		#region BaseClassTemplate overrides
		public override string FileName
		{
			get
			{
				return string.Format("Domain{0}.Generated.cs", _currentStoredProcedure.PascalName);
			}
		}

		public string ParentItemName
		{
			get
			{
				return string.Format("Domain{0}.cs", _currentStoredProcedure.PascalName);
			}
		}

		public override string FileContent
		{
			get
			{
				GenerateContent();
				return sb.ToString();
			}
		}
		#endregion

		private void GenerateContent()
		{
			try
			{
				Widgetsphere.Generator.GenerationHelper.AppendCopyrightInCode(sb, _model);
				this.AppendUsingStatements();        
				sb.AppendLine("namespace " + this.GetLocalNamespace() + ".Domain.StoredProcedures" );
				sb.AppendLine("{" );
				this.AppendClass();
				sb.AppendLine("}" );
			}
			catch(Exception ex)
			{
				throw;
			}
		}

		#region namespace / objects
		public void AppendUsingStatements()
		{
			sb.AppendLine("using System;" );
			sb.AppendLine("using System.Data;" );
			sb.AppendLine("using System.Xml;" );
			sb.AppendLine("using System.Runtime.Serialization;" );
			sb.AppendLine("using System.Collections;" );
			sb.AppendLine("using Widgetsphere.Core.Exceptions;" );
			sb.AppendLine("using Widgetsphere.Core.DataAccess;" );
			sb.AppendLine("using " + this.GetLocalNamespace() + ".Business;" );
			sb.AppendLine("using " + this.GetLocalNamespace() + ".Business.Objects;" );
			sb.AppendLine("using " + this.GetLocalNamespace() + ".Business.StoredProcedures;" );
			sb.AppendLine("using " + this.GetLocalNamespace() + ".Business.Rules;" );
			sb.AppendLine("using " + this.GetLocalNamespace() + ".Business.SelectCommands;" );
			sb.AppendLine();
		}

		private void AppendClass()
		{
			sb.AppendLine("	/// <summary>" );
			sb.AppendLine("	/// This is an customizable extender for the domain class associated with the '" + _currentStoredProcedure.PascalName + "' object" );
			sb.AppendLine("	/// </summary>" );
			sb.AppendLine("	[Serializable()]" );
			sb.AppendLine("	partial class Domain" + _currentStoredProcedure.PascalName + " : ReadOnlyDomainObjectBase " );
			sb.AppendLine("	{" );
			this.AppendTemplate();
			sb.AppendLine("	}" );
		}

		#endregion

		#region append regions
		private void AppendRegionRelationshipMethods()
		{
			sb.AppendLine("		#region Relationship Methods" );
			sb.AppendLine();
			sb.AppendLine("		#endregion" );
		}
		#endregion

		#region append member variables
		public void AppendMemberVariables()
		{
			sb.AppendLine("		private Domain" + _currentStoredProcedure.PascalName + "Collection col" + _currentStoredProcedure.PascalName + "List;" );
		}
		#endregion

		#region append constructors
		public void AppendConstructor()
		{
			sb.AppendLine("		Domain " + _currentStoredProcedure.PascalName + "CollectionRules(Domain" + _currentStoredProcedure.PascalName + "Collection in" + _currentStoredProcedure.PascalName + "List)" );
			sb.AppendLine("		{" );
			sb.AppendLine("			col" + _currentStoredProcedure.PascalName + "List = in" + _currentStoredProcedure.PascalName + "List;" );
			sb.AppendLine("			Initialize();" );
			sb.AppendLine("		}" );
		}
		#endregion

		#region append properties
		#endregion

		#region append methods
		public void AppendInitializeMethod()
		{
			sb.AppendLine("		private void Initialize()" );
			sb.AppendLine("		{" );
			sb.AppendLine("		}" );
		}

		#endregion

		private void AppendTemplate()
		{
			sb.AppendLine("		#region Member Variables" );
			sb.AppendLine();
			sb.AppendLine("		internal Domain" + _currentStoredProcedure.PascalName + "Collection ParentCol;" );
			sb.AppendLine();
			sb.AppendLine("		#endregion" );
			sb.AppendLine();
			sb.AppendLine("		#region Constructor" );
			sb.AppendLine();
			sb.AppendLine("		internal Domain" + _currentStoredProcedure.PascalName + "(DataRowBuilder rb) : base(rb) " );
			sb.AppendLine("		{" );
			sb.AppendLine("			this.ParentCol = ((Domain" + _currentStoredProcedure.PascalName + "Collection)(base.Table));" );
			sb.AppendLine("		}" );
			sb.AppendLine();
			sb.AppendLine("		#endregion" );
			sb.AppendLine();
			sb.AppendLine("		#region Properties" );
			sb.AppendLine();

			foreach (var column in _currentStoredProcedure.GeneratedColumns)
			{        
				sb.AppendLine();
				sb.AppendLine("		internal " + column.GetCodeType() + " " + column.PascalName + "" );
				sb.AppendLine("		{" );
				if (column.AllowNull)
				{
					sb.AppendLine("			get");
					sb.AppendLine("			{");
					sb.AppendLine("				try");
					sb.AppendLine("				{");
					sb.AppendLine("					if (base[this.ParentCol." + column.PascalName + "Column] == System.DBNull.Value)");
					sb.AppendLine("						return null;");
					sb.AppendLine("					else");
					sb.AppendLine("						return ((" + column.GetCodeType() + ")(base[this.ParentCol." + column.PascalName + "Column]));");
					sb.AppendLine("				}");
					sb.AppendLine("				catch (InvalidCastException e)");
					sb.AppendLine("				{");
					sb.AppendLine("					throw new StrongTypingException(\"The value is null and in an invalid state.\", e);");
					sb.AppendLine("				}");
					sb.AppendLine("			}");
				}
				else //Does not allow null
				{
					sb.AppendLine("			get");
					sb.AppendLine("			{");
					sb.AppendLine("				try");
					sb.AppendLine("				{");
					if (column.IsTextType)
					{
						sb.AppendLine("					if (base[this.ParentCol." + column.PascalName + "Column] == System.DBNull.Value)");
						sb.AppendLine("						return null;");
						sb.AppendLine("					else");
						sb.AppendLine("						return ((" + column.GetCodeType() + ")(base[this.ParentCol." + column.PascalName + "Column]));");
					}
					else
					{
						sb.AppendLine("					return ((" + column.GetCodeType() + ")(base[this.ParentCol." + column.PascalName + "Column]));");
					}
					sb.AppendLine("				}");
					sb.AppendLine("				catch (InvalidCastException e)");
					sb.AppendLine("				{");
					sb.AppendLine("					throw new StrongTypingException(\"The value is null and in an invalid state.\", e);");
					sb.AppendLine("				}");
					sb.AppendLine("			}");
				} 
				sb.AppendLine("		}");
			}

			sb.AppendLine();
			sb.AppendLine("		#endregion" );
			sb.AppendLine();


			sb.AppendLine("		#region Null Methods" );
			sb.AppendLine();

			foreach (var column in _currentStoredProcedure.GeneratedColumns)
			{        
				if(column.AllowNull)
				{
					sb.AppendLine();
					sb.AppendLine("		internal bool Is" + column.PascalName + "Null() " );
					sb.AppendLine("		{" );
					sb.AppendLine("			return base.IsNull(this.ParentCol." + column.PascalName + "Column);" );
					sb.AppendLine("		}" );
					sb.AppendLine();
				}
			}

			sb.AppendLine();
			sb.AppendLine("		#endregion" );
			sb.AppendLine();
			AppendRegionRelationshipMethods();
			sb.AppendLine();
			sb.Append("#region Remove");
			sb.AppendLine();
			sb.AppendLine("		internal void Remove()");
			sb.AppendLine("		{");
			sb.AppendLine("			this.ParentCol.Remove" + _currentStoredProcedure.PascalName + "(this);");
			sb.AppendLine("		}");
			sb.AppendLine();
			sb.Append("#endregion");
			sb.AppendLine();

		}

	}
}